package com.wtwd.campus.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wtwd.campus.common.Constants;
import com.wtwd.campus.constant.SignConstant;
import com.wtwd.campus.dao.CommandRecordMapper;
import com.wtwd.campus.dao.CustomerMapper;
import com.wtwd.campus.entity.*;
import com.wtwd.campus.fjryE15.untils.XyyUtiils;
import com.wtwd.campus.hxy.model.entity.HxyFence;
import com.wtwd.campus.hxy.service.HxyFenceService;
import com.wtwd.campus.service.*;
import com.wtwd.campus.utils.Vizhi.VizhiService;
import com.wtwd.campus.utils.Vizhi.entity.Address;
import com.wtwd.campus.utils.Vizhi.entity.vo.VizhiGeocodingVo;
import com.wtwd.campus.utils.Vizhi.entity.vo.VizhiLocationVo;
import com.wtwd.campus.vcom.common.Constant;
import com.wtwd.campus.vcom.entity.VcomCircleFence;
import com.wtwd.campus.vcom.entity.VcomH5Fence;
import com.wtwd.campus.vcom.entity.VcomWarningRecord;
import com.wtwd.campus.vcom.service.VcomFenceService;
import com.wtwd.campus.vcom.service.VcomH5Service;
import com.wtwd.campus.vcom.utils.VcomPushUtils;
import com.wtwd.campus.wx.service.WxUtilsService;
import com.wtwd.campus.wx.utils.PushModel;
import com.wtwd.campus.wx.utils.WxUtils;
import org.apache.commons.lang.StringUtils;
import org.jeewx.api.core.req.model.message.TemplateMessageSendResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.*;

/**
 * 该工具类用于收到设备指令回复之后需要进行的共有操作
 */
@Component
public class ReceiverUtils {

    private static final Logger logger = LoggerFactory.getLogger(ReceiverUtils.class);

    @Autowired
    private GouldUtil gouldUtil;
    @Autowired
    private DeviceInfoService deviceInfoService;
    @Autowired
    private LocationService locationService;
    @Resource
    private CommandRecordMapper commandRecordMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private FenceInfoService fenceInfoService;
    @Autowired
    private WarningRecordService warningRecordService;
    @Autowired
    private WXPushUtils wxPushUtils;
    @Autowired
    private WxService wxService;
    @Resource
    private CustomerMapper customerMapper;
    @Resource
    private PushUtils pushUtils;
    @Resource
    private HxyFenceService hxyFenceService;
    @Resource
    private StudentService studentService;
    @Autowired
    private IRMFeignClientService irmFeignClientService;
    @Autowired
    private VcomFenceService vcomFenceService;
    @Autowired
    private VcomPushUtils vcomPushUtils;
    @Autowired
    private VcomH5Service vcomH5Service;
    @Autowired
    private WxUtilsService wxUtilsService;
    @Autowired
    @Qualifier("CustomerDealCmdServiceImpl")
    private CustomerDealCmdService customerDealCmdService;
    @Autowired
    private LastLocationDataService lastLocationDataService;
    @Resource
    private LocationSubmeterService locationSubmeterService;

    @Resource
    private VizhiService vizhiService;

    @Value("${h5.customerId.ryh5}")
    private Integer ryh5CustomerId;

    @Value("${h5.customerId.hbDxRyh5}")
    private Integer hbDxRyh5CustomerId;

    @Value("${wx.general.push.customerCode}")
    private String wxPushcustomerCode;

    /**
     * 处理定位数据
     *
     * @param mqLocationData
     * @param locationTime
     * @param deviceInfo
     * @return
     */
    public DeviceInfo dealLocation(MqLocationData mqLocationData, long locationTime, DeviceInfo deviceInfo, int locationType) {
        LocationData locationData = new LocationData();
        Double longitude = mqLocationData.getLongitude();
        Double latitude = mqLocationData.getLatitude();
        String wifAddress = mqLocationData.getAddress();
        // 查询位置使用高德api，所以先转成Gcj02;但是存到数据库中的是原始的GPS数据
        double[] place = GPSUtils.gps84_To_Gcj02(latitude, longitude);
        double lat = place[0];
        double lng = place[1];
        String address = null;
        try {
            if (StringUtils.isBlank(wifAddress)){//处理逆地理编码位置
                VizhiGeocodingVo vizhiGeocodingVo = vizhiService.InverseGeocoding(String.valueOf(longitude), String.valueOf(latitude));
                if (vizhiGeocodingVo!=null){
                    VizhiLocationVo location = vizhiGeocodingVo.getLocation();
                    if (location!=null&&location.getAddress()!=null){
                        Address locationAddress = location.getAddress();
                        address=locationAddress.getName();
                    }
                }
            }else {
                address=wifAddress;
            }
//            address = gouldUtil.getAMapByLngAndLat(String.valueOf(lng), String.valueOf(lat));
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 围栏判断
        int deviceType = deviceInfo.getDeviceType();
        // 是平台设备且有学生绑定了，进入平台围栏判断
        if (deviceType == Constants.PLATFORM_DEVICE && deviceInfo.getStudentId() != null) {
            platformFenceDecision(longitude, latitude, deviceInfo.getDeviceId(), address, locationTime);
        }
        // 云对接客户.  H5客户。如果有围栏，可以添加
        else if (deviceType == Constants.CUSTOMER_DEVICE) {
            // 客户定位数据推送处理
            pushUtils.pushLocationData(mqLocationData, locationType == 2 ? 3 : locationType, locationTime, deviceInfo);
            customerFenceDecision(mqLocationData, deviceInfo, address, locationTime);
        } else if (deviceType == Constants.HXY_DEVICE) {
            // 和校园围栏处理
            hxyFenceDecision(longitude, latitude, deviceInfo.getDeviceId(), deviceInfo.getImei(), locationTime);
        } else if (deviceType == Constants.H5_DEVICE) {
            // H5围栏处理
            h5CustomerFenceDecision(mqLocationData, deviceInfo, address, locationTime, locationType);
            if (ryh5CustomerId.equals(deviceInfo.getCustomerId())) {//如果是睿翼e15的客户进行定位数据推送处理
                PositionReport positionReport = new PositionReport();
                positionReport.setImei(deviceInfo.getImei());
                positionReport.setLat(String.valueOf(mqLocationData.getLatitude()));
                positionReport.setLng(String.valueOf(mqLocationData.getLongitude()));
                positionReport.setPosition(address);
                positionReport.setPushType("0");
                Date date = new Date(locationTime);
                positionReport.setReportTime(DateUtils.format(date, DateUtils.dateFormat15));
                XyyUtiils.pushPositionReport(positionReport);
            }
        } else if (deviceType == Constants.VCOM_DEVICE) {
            // TODO 威科姆围栏处理（威科姆围栏 + H5设置的围栏）
            vcomFenceDeal(mqLocationData, deviceInfo, address, locationTime);
        }
        try {
            customerDealCmdService.dealCustomerPolygonFence(mqLocationData, deviceInfo, address, locationTime);
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("多边形围栏处理异常 异常为={}",e.getMessage());
        }
        locationData.setLongitude(String.valueOf(longitude));
        locationData.setLatitude(String.valueOf(latitude));
        locationData.setAddress(address);
        locationData.setDevice_id(deviceInfo.getDeviceId());
        locationData.setDevice_imei(deviceInfo.getImei());
        locationData.setLocation_time(locationTime);
        locationData.setLocation_type(locationType);

        //维智物联接口429导致address为空的处理
        if(locationData.getAddress() != null){
            locationService.addLocationData(locationData);
            LastLocationData data = new LastLocationData();
            BeanUtils.copyProperties(locationData,data);
            data.setDeviceId(locationData.getDevice_id());
            data.setLocationTime(locationData.getLocation_time());
            data.setLocationType(locationData.getLocation_type());
            data.setDeviceImei(locationData.getDevice_imei());
            lastLocationDataService.InsertOrUpdate(data);
            //设置返回设备信息
            deviceInfo.setAddress(address);
            deviceInfo.setSpeed(mqLocationData.getSpeed());
            //此处新增分表定位存储处理
            try {
                LocationSubmeter locationSubmeter = new LocationSubmeter();
                locationSubmeter.setDeviceId(locationData.getDevice_id());
                locationSubmeter.setLongitude(locationData.getLongitude());
                locationSubmeter.setLatitude(locationData.getLatitude());
                locationSubmeter.setLocationTime(locationData.getLocation_time());
                locationSubmeter.setAddress(locationData.getAddress());
                locationSubmeter.setLocationType(locationData.getLocation_type());
                locationSubmeterService.save(locationSubmeter,deviceInfo.getImei());
            } catch (Exception e) {
                e.printStackTrace();
                logger.info("分表定位存储出路 异常为={}",e.getMessage());
            }
        }

        return deviceInfo;

    }

    /**
     * 完善指令下发记录
     *
     * @param type
     * @param imei
     * @param commandNumber
     * @param sequence
     * @param result
     * @param time
     */
    public void completeCommandRecord(String type, String imei, String commandNumber, Integer sequence, Integer result, Long time) {
        CommandRecord record = new CommandRecord();
        record.setDeviceImei(imei);
        record.setResult(result);
        record.setCommandNumber(commandNumber);
        record.setEndTime(time);
        record.setCommandType(type);
        record.setSequence(sequence);
        //完善指令发送结果
        commandRecordMapper.completeCommandRecord(record);
    }

    /**
     * 删除缓存中的指令
     *
     * @param imei
     * @param commandNumber
     */
    public void deleteCommandInRedis(String imei, String commandNumber) {
        redisService.deleteCommand(imei, commandNumber);
    }

    /**
     * 平台围栏决策
     *
     * @param longitude
     * @param latitude
     * @param deviceId
     * @param address
     * @param time
     */
    public void platformFenceDecision(Double longitude, Double latitude, Integer deviceId, String address, Long time) {
        //获取该设备的上一个定位地点
        LocationData lastLocation = locationService.getLatestLocationData(deviceId);
        if (lastLocation != null) {
            double lastLgn = Double.parseDouble(lastLocation.getLongitude());
            double lastLat = Double.parseDouble(lastLocation.getLatitude());
            //根据imei号查询出设备所属围栏信息
            List<FenceInfo> fenceInfoList = fenceInfoService.getFenceInfoByDeviceId(deviceId);
            //根据imei查询设备
            DeviceInfo device = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
            //当设备绑定学生之后，查询出微信端给该设备添加的围栏
            List<FenceInfo> wxFenceInfo = fenceInfoService.getFenceInfoListByStuId(device.getStudentId());
            if (wxFenceInfo != null && wxFenceInfo.size() != 0) {
                //整合两种属于该设备的围栏
                fenceInfoList.addAll(wxFenceInfo);
            }
            if (fenceInfoList == null || fenceInfoList.size() == 0) {
                return;
            }
            // 遍历，
            for (FenceInfo fence : fenceInfoList) {
                if (fence == null) {
                    continue;
                }
                int fenceType = fence.getAlter_type();
                int radius = fence.getRadius();
                double fenceLgn = fence.getLongitude();
                double fenceLat = fence.getLatitude();
                double nowDistance = GPSUtils.getDistance(longitude, latitude, fenceLgn, fenceLat);
                // 上一个点距离
                double lastDistance = GPSUtils.getDistance(lastLgn, lastLat, fenceLgn, fenceLat);
                int flag = 0;
                // 进围栏判断 1 3
                if (lastDistance > radius && nowDistance < radius) {
                    if (fenceType != Constants.LEFT_WARNING) {
                        flag = Constants.ENTER_FENCE_WARNING_TYPE;
                    }
                }
                // 出围栏  2 3
                else if (lastDistance < radius && nowDistance > radius) {
                    if (fenceType != Constants.ENTER_WARNING) {
                        flag = Constants.LEFT_WARNING_TYPE;
                    }
                } else {
                    continue;
                }
                if (flag != 0) {
                    //需要存储围栏告警
                    WarningRecord record = new WarningRecord();
                    record.setDevice_id(deviceId);
                    record.setAddress(address);
                    record.setWarning_time(time);
                    record.setWarning_type(flag);
                    record.setFenceName(fence.getFence_name());
                    warningRecordService.addWarningRecord(record);
                    //判断是否是微信围栏消息，如果是则进行推送
                    if (fence.getStudent_id() != null) {
                        TemplateMessageSendResult generalTemplate = null;
                        String customerCode = "";
                        TemplateMessageSendResult template = null;
                        TemplateMessageSendResult templateRy = null;
                        TemplateMessageSendResult templateCW = null;
                        TemplateMessageSendResult templateXB = null;
                        Map<String, Object> student = studentService.getStuNameAndClassNameByStuId(fence.getStudent_id());
                        String stuName = (String) student.get("student_name");
                        String className = (String) student.get("classes_name");
                        if (flag != Constants.LEFT_WARNING_TYPE) {
                            template = PushModel.createEntryFenceTemplate(device.getImei(), stuName, fence.getFence_name());
                            templateRy = PushModel.createEntryFenceTemplateRy(device.getImei(), stuName, fence.getFence_name());
                            templateCW = PushModel.createEntryFenceTemplateCW(device.getImei(), stuName, fence.getFence_name());
//                            templateXB = PushModel.createEntryFenceTemplateXB(device.getImei(), stuName, fence.getFence_name());
                            if (StringUtils.isNotBlank(wxPushcustomerCode) && StringUtils.isNotBlank(device.getOrgCode())) {
                                List<String> customerCodeString = Arrays.asList(wxPushcustomerCode.split(SignConstant.COMMA));
                                if (customerCodeString != null && customerCodeString.size() > 0) {
                                    String pushCode = wxUtilsService.getWxCustomerCode(customerCodeString, device.getOrgCode());
                                    if (StringUtils.isNotBlank(pushCode)) {
                                        customerCode = pushCode;
                                        generalTemplate = wxUtilsService.createEntryFenceTemplate(pushCode, device.getImei(), stuName, fence.getFence_name());
                                    }
                                }
                            }
                        } else {
                            template = PushModel.createOutFenceTemplate(stuName, className, fence.getFence_name(), nowDistance - radius);
                            templateRy = PushModel.createOutFenceTemplateRy(stuName, className, fence.getFence_name(), nowDistance - radius);
                            templateCW = PushModel.createOutFenceTemplateCW(stuName, className, fence.getFence_name(), nowDistance - radius);
//                            templateXB = PushModel.createOutFenceTemplateXB(stuName, className, fence.getFence_name(), nowDistance - radius);
                            if (StringUtils.isNotBlank(wxPushcustomerCode) && StringUtils.isNotBlank(device.getOrgCode())) {
                                List<String> customerCodeString = Arrays.asList(wxPushcustomerCode.split(SignConstant.COMMA));
                                if (customerCodeString != null && customerCodeString.size() > 0) {
                                    String pushCode = wxUtilsService.getWxCustomerCode(customerCodeString, device.getOrgCode());
                                    if (StringUtils.isNotBlank(pushCode)) {
                                        customerCode = pushCode;
                                        generalTemplate = wxUtilsService.createOutFenceTemplate(pushCode, device.getImei(), stuName, className, fence.getFence_name(), nowDistance - radius);
                                    }
                                }
                            }
                        }
                        //获取该学生被授权的所有家长的openId
                        List<Map<String, Object>> openIdList = wxService.getOpenIdByStuId(fence.getStudent_id());
                        for (Map<String, Object> map : openIdList) {
                            String openId = (String) map.get("open_id");
                            //推送到平台公众号
                            template.setTouser(openId);
                            WxUtils.pushMsg(template);
                            //推送到瑞翼公众号
                            templateRy.setTouser(openId);
                            WxUtils.pushMsgRy(templateRy);
                            //推送到长虹公众号
                            templateCW.setTouser(openId);
                            WxUtils.pushMsgCW(templateCW);
              /*              //推送到小湃公众号
                            templateXB.setTouser(openId);
                            WxUtils.pushMsgXB(templateXB);*/
                            //以上代码已经正常运行不在进行通用客户处理(怕影响客户使用以及代码执行)
                            if (generalTemplate != null && StringUtils.isNotBlank(customerCode)) {
                                generalTemplate.setTouser(openId);
                                wxUtilsService.pushMsg(customerCode, generalTemplate);
                            }
                        }
                    } else {
                        //是平台的围栏，也进行微信推送
                        TemplateMessageSendResult generalTemplate = null;
                        String customerCode = "";
                        TemplateMessageSendResult template = null;
                        TemplateMessageSendResult templateRy = null;
                        TemplateMessageSendResult templateCW = null;
                        TemplateMessageSendResult templateXB = null;

                        //获取推送的信息
                        //根据设备id获取学生姓名和班级姓名
                        Map<String, Object> map = studentService.getStuNameAndClassNameByDeviceId(deviceId);
                        if (map.get("student_name") != null && map.get("classes_name") != null) {
                            //当设备绑定了学生才进行推送
                            String stuName = (String) map.get("student_name");
                            String className = (String) map.get("classes_name");
                            Integer stuId = (Integer) map.get("student_id");
                            if (flag != Constants.LEFT_WARNING_TYPE) {
                                template = PushModel.createEntryFenceTemplate(device.getImei(), stuName, fence.getFence_name());
                                templateRy = PushModel.createEntryFenceTemplateRy(device.getImei(), stuName, fence.getFence_name());
                                templateCW = PushModel.createEntryFenceTemplateCW(device.getImei(), stuName, fence.getFence_name());
//                                templateXB = PushModel.createEntryFenceTemplateXB(device.getImei(), stuName, fence.getFence_name());
                                if (StringUtils.isNotBlank(wxPushcustomerCode) && StringUtils.isNotBlank(device.getOrgCode())) {
                                    List<String> customerCodeString = Arrays.asList(wxPushcustomerCode.split(SignConstant.COMMA));
                                    if (customerCodeString != null && customerCodeString.size() > 0) {
                                        String pushCode = wxUtilsService.getWxCustomerCode(customerCodeString, device.getOrgCode());
                                        if (StringUtils.isNotBlank(pushCode)) {
                                            customerCode = pushCode;
                                            generalTemplate = wxUtilsService.createEntryFenceTemplate(pushCode, device.getImei(), stuName, fence.getFence_name());
                                        }
                                    }
                                }
                            } else {
                                template = PushModel.createOutFenceTemplate(stuName, className, fence.getFence_name(), nowDistance - radius);
                                templateRy = PushModel.createOutFenceTemplateRy(stuName, className, fence.getFence_name(), nowDistance - radius);
                                templateCW = PushModel.createOutFenceTemplateCW(stuName, className, fence.getFence_name(), nowDistance - radius);
//                                templateXB = PushModel.createOutFenceTemplateXB(stuName, className, fence.getFence_name(), nowDistance - radius);
                                if (StringUtils.isNotBlank(wxPushcustomerCode) && StringUtils.isNotBlank(device.getOrgCode())) {
                                    List<String> customerCodeString = Arrays.asList(wxPushcustomerCode.split(SignConstant.COMMA));
                                    if (customerCodeString != null && customerCodeString.size() > 0) {
                                        String pushCode = wxUtilsService.getWxCustomerCode(customerCodeString, device.getOrgCode());
                                        if (StringUtils.isNotBlank(pushCode)) {
                                            customerCode = pushCode;
                                            generalTemplate = wxUtilsService.createOutFenceTemplate(pushCode, device.getImei(), stuName, className, fence.getFence_name(), nowDistance - radius);
                                        }
                                    }
                                }
                            }
                            //获取该学生被授权的所有家长的openId
                            List<Map<String, Object>> openIdList = wxService.getOpenIdByStuId(stuId);
                            for (Map<String, Object> map2 : openIdList) {
                                String openId = (String) map2.get("open_id");
                                //推送到平台公众号
                                template.setTouser(openId);
                                WxUtils.pushMsg(template);
                                //推送到瑞翼公众号
                                templateRy.setTouser(openId);
                                WxUtils.pushMsgRy(templateRy);
                                //推送到长虹公众号
                                templateCW.setTouser(openId);
                                WxUtils.pushMsgCW(templateCW);
                       /*         //推送到小湃公众号
                                templateXB.setTouser(openId);
                                WxUtils.pushMsgXB(templateXB);*/
                                //以上代码已经正常运行不在进行通用客户处理(怕影响客户使用以及代码执行)
                                if (generalTemplate != null && StringUtils.isNotBlank(customerCode)) {
                                    generalTemplate.setTouser(openId);
                                    wxUtilsService.pushMsg(customerCode, generalTemplate);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 客户围栏决策
     *
     * @param mqLocationData
     * @param deviceInfo
     * @param address
     * @param time
     */
    public void customerFenceDecision(MqLocationData mqLocationData, DeviceInfo deviceInfo, String address, Long time) {
        //获取该设备的上一个定位地点
        LocationData lastLocation = locationService.getLatestLocationData(deviceInfo.getDeviceId());
        if (lastLocation != null) {
            double lastLgn = Double.parseDouble(lastLocation.getLongitude());
            double lastLat = Double.parseDouble(lastLocation.getLatitude());
            List<CustomerFence> customerFenceList = customerMapper.getDeviceFenceList(deviceInfo.getImei());
            if (customerFenceList == null || customerFenceList.size() == 0) {
                return;
            }
            for (CustomerFence fence : customerFenceList) {
                int fenceType = fence.getFenceType();
                int radius = fence.getRadius();
                double fenceLgn = Double.parseDouble(fence.getLongitude());
                double fenceLat = Double.parseDouble(fence.getLatitude());
                // 当前距离
                double nowDistance = GPSUtils.getDistance(mqLocationData.getLongitude(), mqLocationData.getLatitude(), fenceLgn, fenceLat);
                // 上一个点距离
                double lastDistance = GPSUtils.getDistance(lastLgn, lastLat, fenceLgn, fenceLat);
                // 判断是否在时间段内
                String timeStr = DateUtils.format(new Date(time), DateUtils.dateFormat8);
                String timePeriod = fence.getTimePeriod();
                if (StringUtils.isBlank(timePeriod)) {
                    continue;
                }
                List<CustomerFencePeriod> customerFencePeriods = JSONArray.parseArray(fence.getTimePeriod(), CustomerFencePeriod.class);
                for (CustomerFencePeriod period : customerFencePeriods) {
                    if (period.getBeginTime().compareTo(timeStr) < 0 && timeStr.compareTo(period.getEndTime()) < 0) {
                        boolean needPush = false;
                        // 进围栏
                        if (lastDistance > radius && nowDistance < radius) {
                            if (fenceType == 0||fenceType==2) {
                                needPush = true;
                                fenceType=0;
                            }
                        }
                        // 出围栏
                        else if (lastDistance < radius && nowDistance > radius) {
                            if (fenceType == 1||fenceType==2) {
                                needPush = true;
                                fenceType=1;
                            }
                        } else {
                            continue;
                        }
                        if (needPush) {
                            pushUtils.pushFenceWarn(deviceInfo, mqLocationData, fence.getId(), fenceType);
                            break;
                        }
                    }
                }
            }
        }
    }

    /**
     * H5围栏决策
     *
     * @param mqLocationData
     * @param deviceInfo
     * @param address
     * @param time
     */
    public void h5CustomerFenceDecision(MqLocationData mqLocationData, DeviceInfo deviceInfo, String address, Long time, Integer locationType) {
        //获取该设备的上一个定位地点
        LocationData lastLocation = locationService.getLatestLocationData(deviceInfo.getDeviceId());
        if (lastLocation != null) {
            double lastLgn = Double.parseDouble(lastLocation.getLongitude());
            double lastLat = Double.parseDouble(lastLocation.getLatitude());
            List<CustomerFence> customerFenceList = customerMapper.getDeviceFenceList(deviceInfo.getImei());
            if (customerFenceList == null || customerFenceList.size() == 0) {
                return;
            }
            for (CustomerFence fence : customerFenceList) {
                int fenceType = fence.getFenceType();
                int radius = fence.getRadius();
                double fenceLgn = Double.parseDouble(fence.getLongitude());
                double fenceLat = Double.parseDouble(fence.getLatitude());
                // 当前距离
                double nowDistance = GPSUtils.getDistance(mqLocationData.getLongitude(), mqLocationData.getLatitude(), fenceLgn, fenceLat);
                // 上一个点距离
                double lastDistance = GPSUtils.getDistance(lastLgn, lastLat, fenceLgn, fenceLat);
                /*List<CustomerFencePeriod> customerFencePeriods = JSONArray.parseArray(fence.getTimePeriod(), CustomerFencePeriod.class);*/
                /*for (CustomerFencePeriod period : customerFencePeriods) {*/
                boolean needPush = false;
                int warnType = 0;
                // 进围栏
                if (lastDistance > radius && nowDistance < radius) {
                    if (fenceType == 0 || fenceType == 2) {
                        needPush = true;
                        warnType = Constants.ENTER_FENCE_WARNING_TYPE;
                    }
                }
                // 出围栏
                else if (lastDistance < radius && nowDistance > radius) {
                    if (fenceType == 1 || fenceType == 2) {
                        needPush = true;
                        warnType = Constants.LEFT_WARNING_TYPE;
                    }
                } else {
                    continue;
                }
                if (needPush) {
                    //存储围栏告警信息
                    WarningRecord record = new WarningRecord();
                    record.setAddress(address);
                    record.setWarning_time(time);
                    record.setWarning_type(warnType);
                    record.setDevice_id(deviceInfo.getDeviceId());
                    record.setFenceName(fence.getFenceName());
                    warningRecordService.addWarningRecord(record);
                    Integer pushFenceType = 0;
                    if (warnType == Constants.ENTER_FENCE_WARNING_TYPE) {//根据推送文档1.进，2出
                        pushFenceType = 1;
                    } else {
                        pushFenceType = 2;
                    }
                    if (deviceInfo.getCustomerId() == 5 || deviceInfo.getCustomerId() == 8) {//睿翼,长虹H5,都走湖南和教育推送接口
                        String locationTime = DateUtils.format(new Date(time), DateUtils.dateFormat1);
                        pushUtils.hnh5PushAlarmInfo(deviceInfo.getImei(), "围栏报警", locationTime, address, pushFenceType, fence.getFenceName());
                    } else if (ryh5CustomerId.equals(deviceInfo.getCustomerId())) {
                        RyE15FenceReport ryE15FenceReport = new RyE15FenceReport();
                        ryE15FenceReport.setImei(deviceInfo.getImei());
                        ryE15FenceReport.setFenceInfo(JSONObject.toJSONString(fence));
                        ryE15FenceReport.setLng(String.valueOf(mqLocationData.getLongitude()));
                        ryE15FenceReport.setLat(String.valueOf(mqLocationData.getLatitude()));
                        ryE15FenceReport.setPosition(address);
                        String rylocationType = "";
                        if (locationType == 1) {//平台为gps
                            rylocationType = "3";
                        } else if (locationType == 2) {//平台为wifi
                            rylocationType = "1";
                        } else if (locationType == 3) {//lbs
                            rylocationType = "2";
                        }
                        ryE15FenceReport.setMode(rylocationType);
                        ryE15FenceReport.setType(String.valueOf(pushFenceType));
                        ryE15FenceReport.setReportTime(DateUtils.format(new Date(time), DateUtils.dateFormat15));
                        XyyUtiils.pushFenceInfo(ryE15FenceReport);
                    } else if (hbDxRyh5CustomerId.equals(deviceInfo.getCustomerId())) {
                        HbDxE15RyPushEntity hbDxE15RyPushEntity = new HbDxE15RyPushEntity();
                        hbDxE15RyPushEntity.setImei(deviceInfo.getImei());
                        hbDxE15RyPushEntity.setmType(HbDxE15RyPushEntity.PushTypeEnum.ALARM_TYPE.getType());
                        hbDxE15RyPushEntity.setmClass(HbDxE15RyPushEntity.MessageType.FENCE_MESSAGE.getType());
                        hbDxE15RyPushEntity.setmTime(DateUtils.format(new Date(time), DateUtils.dateFormat4));
                        hbDxE15RyPushEntity.setMemo(MessageFormat.format(HbDxE15RyPushEntity.MessageType.FENCE_MESSAGE.getTemplate(), deviceInfo.getImei(), address, fence.getFenceName(), pushFenceType == 1 ? "进" : "出", DateUtils.format(new Date(time), DateUtils.dateFormat4)));
                        HbDxE15RyUtiils.hbDxE15RyPush(hbDxE15RyPushEntity);
                    }
                    break;
                }
            }
        }
    }


    /**
     * 和校园围栏处理
     *
     * @param longitude
     * @param latitude
     * @param deviceId
     * @param imei
     * @param time
     */
    public void hxyFenceDecision(Double longitude, Double latitude, Integer deviceId, String imei, Long time) {
        List<HxyFence> fenceByImei = hxyFenceService.getFenceByImei(imei);
        fenceByImei.forEach(item -> {
            if (!isInTime(item.getTimeperiod(), time)) {
                return;
            }
            Integer type = item.getFenceType();
            Double radius = item.getRadius();
            Double flng = Double.valueOf(item.getLongitude());
            Double flat = Double.valueOf(item.getLatitude());
            double nowDistance = GPSUtils.getDistance(longitude, latitude, flng, flat);
            boolean isOutside = nowDistance > radius;
            boolean isWarn = false;
            if (type == 0) {//进栏
                if (!isOutside) {
                    LocationData lastLocation = locationService.getLatestLocationData(deviceId);
                    if (lastLocation != null) {
                        isWarn = GPSUtils.getDistance(Double.valueOf(lastLocation.getLongitude()), Double.valueOf(lastLocation.getLatitude())
                                , flng, flat) > radius;
                    }
                }
            } else if (type == 1) {//出栏
                if (isOutside) {
                    LocationData lastLocation = locationService.getLatestLocationData(deviceId);
                    if (lastLocation != null) {
                        isWarn = GPSUtils.getDistance(Double.valueOf(lastLocation.getLongitude()), Double.valueOf(lastLocation.getLatitude())
                                , flng, flat) < radius;
                    }
                }
            }
            // 经纬度转换
            double[] doubles = GPSUtils.gps84_To_Gcj02(latitude, longitude);
            if (isWarn) {
                pushUtils.pushHxyFenceWarn(imei, type == 0 ? "5" : "6",
                        DateUtils.format(new Date(time), DateUtils.dateFormat4), doubles[1], doubles[0], item.getFenceId());
            }
        });

    }

    /**
     * TODO 威科姆围栏处理
     *
     * @param mqLocationData
     * @param deviceInfo
     * @param address
     * @param locationTime
     */
    public void vcomFenceDeal(MqLocationData mqLocationData, DeviceInfo deviceInfo, String address, Long locationTime) {
        //获取该设备的上一个定位地点
        LocationData lastLocation = locationService.getLatestLocationData(deviceInfo.getDeviceId());
        if (lastLocation != null) {
            double lastLgn = Double.parseDouble(lastLocation.getLongitude());
            double lastLat = Double.parseDouble(lastLocation.getLatitude());
            // 威科姆平台设置的围栏
            List<VcomCircleFence> vcomPlatformfenceList = vcomFenceService.getVcomActiveFenceByImei(deviceInfo.getImei());
            if (vcomPlatformfenceList != null && vcomPlatformfenceList.size() > 0) {
                for (VcomCircleFence fence : vcomPlatformfenceList) {
                    int alarmType = fence.getAlarmType();
                    int radius = fence.getRadius();
                    double fenceLgn = fence.getLongitude();
                    double fenceLat = fence.getLatitude();
                    // 当前距离
                    double nowDistance = GPSUtils.getDistance(mqLocationData.getLongitude(), mqLocationData.getLatitude(), fenceLgn, fenceLat);
                    // 上一个点距离
                    double lastDistance = GPSUtils.getDistance(lastLgn, lastLat, fenceLgn, fenceLat);
                    boolean needPush = false;
                    int type = 3;
                    int platType = Constant.WARNING_PLAT_ENTER_FENCE;
                    // 进围栏
                    if (nowDistance < radius && lastDistance > radius) {
                        if (alarmType == 0 || alarmType == 2) {
                            needPush = true;
                        }
                    } else if (nowDistance > radius && lastDistance < radius) {
                        // 出围栏
                        if (alarmType == 1 || alarmType == 2) {
                            needPush = true;
                            type = 4;
                            platType = Constant.WARNING_PLAT_LEFT_FENCE;
                        }
                    } else {
                        continue;
                    }
                    if (needPush) {
                        String info = "";
                        if (type == 3) {
                            info = "进入电子围栏:".concat(fence.getFenceName());
                        } else if (type == 4) {
                            info = "出电子围栏:".concat(fence.getFenceName());
                        }
                        vcomPushUtils.pushWarning(mqLocationData.getLatitude(), mqLocationData.getLongitude(), address, type, info, locationTime, deviceInfo.getImei(), fence.getFenceName(), fence.getFenceId());
                    }
                    // 保存围栏告警通知
                    List<String> studentIds = vcomH5Service.getStudentIdByImei(deviceInfo.getImei());
                    if (studentIds != null && studentIds.size() > 0) {
                        for (String studentId : studentIds) {
                            VcomWarningRecord record = new VcomWarningRecord();
                            record.setTime(locationTime);
                            record.setType(platType);
                            Map<String, Object> message = new HashMap<>();
                            message.put("fenceName", fence.getFenceName());
                            message.put("address", address);
                            record.setMessage(JSONObject.toJSONString(message));
                            record.setImei(deviceInfo.getImei());
                            record.setStudentId("0");
                            if (!StringUtils.isBlank(studentId)) {
                                record.setStudentId(studentId);
                            }
                            vcomH5Service.addVcomWarningRecord(record);
                        }
                    } else {
                        VcomWarningRecord record = new VcomWarningRecord();
                        record.setTime(locationTime);
                        record.setType(platType);
                        Map<String, Object> message = new HashMap<>();
                        message.put("fenceName", fence.getFenceName());
                        message.put("address", address);
                        record.setMessage(JSONObject.toJSONString(message));
                        record.setImei(deviceInfo.getImei());
                        record.setStudentId("0");
                        vcomH5Service.addVcomWarningRecord(record);
                    }
                }
            }
            //  威科姆H5设置的围栏
            saveVcomH5FenceWarning(deviceInfo, mqLocationData, lastLgn, lastLat, locationTime, address);
        }
    }

    /**
     * 保存威科姆h5围栏的告警信息
     *
     * @param deviceInfo
     * @param mqLocationData
     * @param lastLgn
     * @param lastLat
     * @param locationTime
     * @param address
     */
    public void saveVcomH5FenceWarning(DeviceInfo deviceInfo, MqLocationData mqLocationData, Double lastLgn, Double lastLat, Long locationTime, String address) {
        List<VcomH5Fence> h5FenceList = vcomH5Service.getVcomFenceListByDeviceId(deviceInfo.getDeviceId());
        if (h5FenceList != null && h5FenceList.size() > 0) {
            for (VcomH5Fence fence : h5FenceList) {
                if (fence.getType() == Constant.H5_FENCE_TYPE_CIRCLE) {
                    //圆形围栏处理(威科姆h5围栏没有进出告警设置，所以进出围栏都会存储告警记录)
                    String pointMess = fence.getPointMess();
                    JSONObject mess = JSONObject.parseObject(pointMess);
                    Double longitude = mess.getDouble("longitude");
                    Double latitude = mess.getDouble("latitude");
                    Integer radius = mess.getInteger("radius");
                    // 当前距离
                    double nowDistance = GPSUtils.getDistance(mqLocationData.getLongitude(), mqLocationData.getLatitude(), longitude, latitude);
                    // 上一个点距离
                    double lastDistance = GPSUtils.getDistance(lastLgn, lastLat, longitude, latitude);
                    int platType = 0;
                    // 进围栏
                    if (nowDistance < radius && lastDistance > radius) {
                        platType = Constant.WARNING_H5_ENTER_FENCE;
                    } else if (nowDistance > radius && lastDistance < radius) {
                        // 出围栏
                        platType = Constant.WARNING_H5_LEFT_FENCE;
                    } else {
                        continue;
                    }
                    //存储围栏告警信息
                    List<String> studentIds = vcomH5Service.getStudentIdByImei(deviceInfo.getImei());
                    if (studentIds != null && studentIds.size() > 0) {
                        for (String studentId : studentIds) {
                            if (studentId != null) {
                                VcomWarningRecord record = new VcomWarningRecord();
                                record.setTime(locationTime);
                                record.setType(platType);
                                Map<String, Object> message = new HashMap<>();
                                message.put("fenceName", fence.getFenceName());
                                message.put("address", address);
                                record.setMessage(JSONObject.toJSONString(message));
                                record.setStudentId(studentId);
                                vcomH5Service.addVcomWarningRecord(record);
                            }
                        }
                    }
                } else if (fence.getType() == Constant.H5_FENCE_TYPE_POLYGON) {
                    //todo 多边形围栏处理
                }
            }
        }
    }

    /**
     * 判断定位时间是否在围栏限定时间段内
     *
     * @param timeperiodJsonArray
     * @param locationTime
     * @return
     */
    private boolean isInTime(String timeperiodJsonArray, long locationTime) {
        JSONArray jsonArray = JSONArray.parseArray(timeperiodJsonArray);
        String locationTimeStr = DateUtils.format(new Date(locationTime), DateUtils.dateFormat8);
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject json = jsonArray.getJSONObject(i);
            if (locationTimeStr.compareTo(json.getString("beginTime")) > -1
                    && json.getString("endTime").compareTo(locationTimeStr) > -1) {
                return true;
            }
        }
        return false;
    }

    /**
     * 围栏告警记录的存储
     *
     * @param address
     * @param time
     * @param deviceId
     */
    public void addFenceWarning(String address, Long time, Integer deviceId) {
        //获取该设备的上一个定位地点
        LocationData lastLocation = locationService.getLatestLocationData(deviceId);
        if (lastLocation != null) {
            //根据imei号查询出设备所属围栏信息
            List<FenceInfo> fenceInfoList = fenceInfoService.getFenceInfoByDeviceId(deviceId);
            if (fenceInfoList != null) {
                for (FenceInfo fence : fenceInfoList) {
                    if (fence == null || fence.getFence_id() == null) {
                        //如果设备未绑定学生则跳过
                        continue;
                    }
                    int flag = 0;
                    Integer alterType = fence.getAlter_type();//围栏的告警类型
                    //判断当前位置对于围栏的位置
                    long nowDistance = gouldUtil.getDistanceByAddress(address, fence.getLocation());
                    //判断上一个点位置对于围栏的位置
                    long lastDistance = gouldUtil.getDistanceByAddress(lastLocation.getAddress(), fence.getLocation());
                    if (fence.getRadius() < nowDistance && fence.getRadius() > lastDistance) {
                        //设备出围栏
                        //判断该围栏的报警类型
                        if (alterType != Constants.ENTER_WARNING) {
                            flag = Constants.LEFT_WARNING_TYPE;
                        }
                    } else if (fence.getRadius() > nowDistance && fence.getRadius() < lastDistance) {
                        //设备进围栏
                        //判断该围栏的报警类型
                        if (alterType != Constants.LEFT_WARNING) {
                            flag = Constants.ENTER_FENCE_WARNING_TYPE;
                        }
                    }
                    if (flag != 0) {
                        //需要存储围栏告警
                        WarningRecord record = new WarningRecord();
                        record.setDevice_id(deviceId);
                        record.setAddress(address);
                        record.setWarning_time(time);
                        record.setWarning_type(flag);
                        warningRecordService.addWarningRecord(record);
                    }
                }
            }
        }
    }

    /**
     * 关闭通道
     *
     * @param imei
     */
    public void cloaseChannel(String imei) {
        irmFeignClientService.closeChannel(imei);
    }

    public static void main(String[] args) {
        double nowDistance1 = GPSUtils.getDistance(104.66364498395153, 31.463073163651814, 104.66794121400208, 31.463936579792264);
        System.out.println(String.valueOf(nowDistance1));
        double nowDistance2 = GPSUtils.getDistance(104.65261766167734, 31.46479941629289, 104.66794121400208, 31.463936579792264);
        System.out.println(String.valueOf(nowDistance2));
        double nowDistance3 = GPSUtils.getDistance(104.66533684700687, 31.463109825086075, 104.66794121400208, 31.463936579792264);
        System.out.println(String.valueOf(nowDistance3));
        double nowDistance4 = GPSUtils.getDistance(104.65261766167734, 31.46479941629289, 104.66794121400208, 31.463936579792264);
        System.out.println(String.valueOf(nowDistance4));
        double nowDistance5 = GPSUtils.getDistance(104.65261766167734, 31.46479941629289, 104.66794121400208, 31.463936579792264);
        System.out.println(String.valueOf(nowDistance5));
    }
}
